#include <AtlasBase.h>
#include <AtlasCommon.h>
#include <AtlasClient.h>
#include <StressClient.h>
#include "ExLobbyAutoCase.h"

namespace Atlas
{
	CStressCase* CExLobbyAutoCase::Create()
	{
		return new CExLobbyAutoCase();
	}

	CExLobbyAutoCase::CExLobbyAutoCase() : CStressCase("ExLobbyAutoCase") , m_LobbyStub(this)
	{
		srand(NULL);
		ClearState();
		m_nSuccTimes = m_nFailedTimes = 0;	
	}

	CExLobbyAutoCase::~CExLobbyAutoCase()
	{

	}

	void CExLobbyAutoCase::OnAttach()
	{
		GetClient()->_OnConnectFailed.connect(this, &CExLobbyAutoCase::OnConnectFailed);
		GetClient()->_OnConnect.connect(this, &CExLobbyAutoCase::OnConnect);
		GetClient()->_OnLoginDone.connect(this, &CExLobbyAutoCase::OnLoginDone);
		GetClient()->_OnData.connect(this, &CExLobbyAutoCase::OnData);
	}

	void CExLobbyAutoCase::OnTick()
	{
		switch(GetClient()->GetClientState())
		{
		case Atlas::CClient::CLIENT_NA:
			ClearState();
			GetStressClient()->Login();
			break;
		case Atlas::CClient::CLIENT_LOGINING:
			break;
		case Atlas::CClient::CLIENT_LOGINED:
			//GetStressClient()->Logout();
			OnStateTick();
			break;
		}
	}

	void CExLobbyAutoCase::OnDetach()
	{

	}

	void CExLobbyAutoCase::OnData( _U16 id, _U32 len, const _U8* data )
	{
		m_LobbyStub.OnData((CNodeClient*)(GetClient()), (id>>8), len, data);
	}

	void CExLobbyAutoCase::OnConnectFailed()
	{
		m_nFailedTimes++;
		//ClearState();
	}

	void CExLobbyAutoCase::OnConnect()
	{

	}

	void CExLobbyAutoCase::OnLoginDone()
	{

	}

	void CExLobbyAutoCase::Echo(CClient* pClient, std::string strEcho)
	{
		DDLProxy::LOBBY_C2S<CClient, DDL::TMemoryWriter<1*1024>> Lobby(pClient);
		Lobby.Echo(strEcho.c_str());
	}

	void CExLobbyAutoCase::LoginDone( CClient* pClient )
	{	
		/*
		DDLProxy::LOBBY_C2S<CClient, DDL::TMemoryWriter<1*1024>> Lobby(pClient);
		char szTmp[800];
		memset(szTmp, 32, sizeof(szTmp));
		szTmp[sizeof(szTmp)-1] = '\0';

		for(int i=0; i<100; i++)
		{
			Lobby.Echo(szTmp);
		}*/
	}

	void CExLobbyAutoCase::AvatarList( CClient* pClient, EXLOBBY_AVATAR *list, _U32 count )
	{
		m_nAvatarListCount = count;
		m_eCaseState = CS_LOGINED;
	}

	void CExLobbyAutoCase::NoAvatar( CClient* pClient )
	{
		m_nAvatarListCount = 0;
		m_eCaseState = CS_CREATE_AVATAR;
	}

	void CExLobbyAutoCase::CreateAvatarResult( CClient* pClient, _U32 errcode )
	{
		if(errcode == RET_CODE_SUCC)
		{
			m_aid = 1;
			m_eCaseState = CS_CREATE_AVATAR;
		}
	}

	void CExLobbyAutoCase::AvatarSelected( CClient* pClient, _U32 aid )
	{
		m_aid = aid;
		m_eCaseState = CS_SEL_AVATAR;
	}

	void CExLobbyAutoCase::ListRoomResult( CClient* pClient, ROOM_INFO *lists, _U32 count )
	{
		m_nRoomCount = count;
		for(_U32 i = 0; i < count; ++i)
		{
			m_RoomList[i] = lists[i].id;
		}
		
		m_eCaseState = CS_LIST_ROOM;
	}

	void CExLobbyAutoCase::CreateRoomResult( CClient* pClient, _U64 id )
	{
		m_rid = id;
		m_eCaseState = CS_SENDMSG;
	}

	void CExLobbyAutoCase::ReceiveMessage( CClient* pClient, std::string msg )
	{
		
	}

	void CExLobbyAutoCase::EnterRoomResult( CClient* pClient, _U32 errcode )
	{
		if(errcode == RET_CODE_SUCC)
		{

		}
	}

	void CExLobbyAutoCase::LeaveRoomResult( CClient* pClient, _U32 errcode )
	{
		if(errcode == RET_CODE_SUCC)
		{
			m_rid = ROOM_ID_INVAILD;
			++m_nSuccTimes;
			//pClient->Logout();
			GetStressClient()->Logout();
		}
	}

	void CExLobbyAutoCase::ClearState()
	{
		m_eCaseState = CS_LOGIN_NA;
		m_aid = 0;
		m_rid = ROOM_ID_INVAILD;
		m_nAvatarListCount = -1;
		
		for(int i = 0; i < MAX_ROOM_LIST_LEN; ++i)
		{
			m_RoomList[i] = ROOM_ID_INVAILD;
		}

		m_nRoomCount = -1;
		m_nSendMsgTimes = 0;
		m_nRoomIndex = 0;
	}

	void CExLobbyAutoCase::OnStateTick()
	{
		//return;
		DDLProxy::LOBBY_C2S<CClient, DDL::TMemoryWriter<1*1024>> Lobby(GetClient());
		switch(m_eCaseState)
		{
		case CS_LOGIN_NA :
			{
				m_eCaseState = CS_LOGINED;
			}
			break;

		case CS_WAIT4SER:
			break;

		case CS_LOGINED :
			{
				if(m_nAvatarListCount == -1)
				{
					Lobby.GetAvatar();
					m_eCaseState = CS_WAIT4SER;
				}
				else if(m_nAvatarListCount == 0)
				{
					m_eCaseState = CS_CREATE_AVATAR;
				} 
				else 
				{
					m_eCaseState = CS_SEL_AVATAR;
				}
			}
			break;
		case CS_CREATE_AVATAR:
			{	
				if(m_aid == 0)
				{
					char szName[50];
					memset(szName, 0, 50);
					sprintf(szName, "%s", GetName().c_str());
					Lobby.CreateAvatar(szName);
					m_eCaseState = CS_WAIT4SER;
				} 
				else
				{
					m_eCaseState = CS_LIST_ROOM;
				}
			}
			break;
		case CS_SEL_AVATAR:
			{
				if(m_aid != 0)
				{
					Lobby.SelectAvatar(m_aid);
					m_eCaseState = CS_WAIT4SER;
				}
				else 
				{
					int nRate = rand()%2;
					if(nRate == 0)
					{
						m_eCaseState = CS_CARETE_ROOM;
					}
					else
					{
						m_eCaseState = CS_LIST_ROOM;
					}
				}
			}
			break;
		case CS_LIST_ROOM:
			{
				if(m_nRoomCount == -1)
				{
					int nPage = 0;
					if(m_nRoomIndex == 0)
					{
						nPage = 0;
					}
					else
					{
						nPage = rand()%m_nRoomIndex;
					}

					Lobby.ListRoom(nPage);//page up and down
					m_eCaseState = CS_WAIT4SER;
				}
				else if(m_nRoomCount == 0)
				{
					m_eCaseState = CS_CARETE_ROOM;
				}
				else
				{
					int nRate = rand()%2;
					if(nRate == 0)
					{
						int n = rand()%m_nRoomCount;
						m_rid = m_RoomList[n];
						m_eCaseState = CS_ENTER_ROOM;
					}
					else
					{
						m_nRoomIndex += 10;
						m_nRoomCount = -1;
						m_eCaseState = CS_LIST_ROOM;
					}
				}
			}
			break;
		case CS_CARETE_ROOM:
			{
				if(m_rid == ROOM_ID_INVAILD)
				{
					char szRoom[50];
					sprintf(szRoom, "%s%d", GetName().c_str(), (int)m_eCaseState);
					Lobby.CreateRoom(szRoom);
					m_eCaseState = CS_WAIT4SER;
				}
				else
				{
					m_eCaseState = CS_ENTER_ROOM;
				}
			}
			break;
		case CS_ENTER_ROOM:
			{
				Lobby.EnterRoom(m_rid);
				m_eCaseState = CS_SENDMSG;
			}
			break;
		case CS_SENDMSG:
			{
				if(m_nSendMsgTimes == 0)
				{
					m_nSendMsgTimes = rand()%10;
					break;
				}

				char szMsg[100];
				sprintf(szMsg, "%s%d", GetName().c_str(), (int)m_eCaseState);
				Lobby.SendMessage(szMsg);

				--m_nSendMsgTimes;
				if(m_nSendMsgTimes == 0)
				{
					m_eCaseState = CS_LEAVE_ROOM;
				}
			}
			break;
		case CS_LEAVE_ROOM:
			{
				m_eCaseState = CS_WAIT4SER;
				Lobby.LeaveRoom();
			}
			break;
		}
	}

	void CExLobbyAutoCase::_GetInfo( std::string& info )
	{
		char szMsg[100];
		sprintf(szMsg, "%s	succ %d | failed %d", GetName().c_str(), m_nSuccTimes, m_nFailedTimes);
		info = szMsg;
	}

}